import selectors
import socket

from FPDLCore import MessageDefs
from FPDLCore.BaseClientNet import BaseClientNet

class DownloadWorkerClient(BaseClientNet):
    def __init__(self, imanager, remoteaddr, sel):
        BaseClientNet.__init__(self, remoteaddr, sel)
        self.imanager = imanager
        self.isconnected = False
        self.clear()

    def clear(self):
        self.s_msg = None
        self.s_data = None
        self.r_data = None
        self.r_data_len = 0

    def isidle(self):
        return self.s_data is None and self.r_data_len == 0

    def startdownload(self, begpos, endpos, filepath, ondownloadend):
        if begpos < endpos and self.isidle():
            self.s_msg = MessageDefs.DownloadRequest(begpos, endpos, filepath)
            self.s_data = MessageDefs.serialize(self.s_msg)
            self.r_data_len = endpos - begpos
            self.ondownloadend  = ondownloadend
            if self.isconnected:
                self.waitsend(self.sock)
            return True

    def oncompleted(self, data):
        self.clear()
        self.ondownloadend(data)

    def onconnectionmade(self, conn):
        self.isconnected = True

        self.imanager.register(self)

        if not self.s_data is None:
            self.waitsend(conn)

    def onconnectionfail(self, conn):
        self.imanager.startfail(self)

    def onread(self, conn, data):
        if self.r_data is None:
            if data[0] == 0:
                #Error no data
                print("Error no data")
                return
            else:
                self.r_data = data[1:]
        else:
            self.r_data += data
            if len(self.r_data) > self.r_data_len:
                # Error data to long
                return
            elif len(self.r_data) == self.r_data_len:
                # Completed
                self.oncompleted(self.r_data)
                return

    def onsend(self, conn):
        if self.s_data:
            sended = conn.send(self.s_data)
            if sended < len(self.s_data):
                self.s_data = self.s_data[sended:]
            else:
                self.waitread(conn)
        else:
            self.waitread(conn)

    def onclose(self, conn):
        self.isconnected = False
        self.imanager.unregister(self)

